package main

import (
	"dkdns/dkFramework/configs"
	"dkdns/dkFramework/logger"
	dkdnserver "dkdns/dnsServer"
	"fmt"
	"os"
	"runtime"
	"runtime/debug"
	"time"

	"go.uber.org/zap"
)

// 编译时注入版本信息（示例）
var (
	version    = "1.0.0"
	buildTime  = "2023-10-01"
	commitHash = "unknown"
)

func main() {
	// 设置 GOMAXPROCS 为 1，减少并发开销
	runtime.GOMAXPROCS(1)

	// 设置最大内存限制（例如：64MB）
	var memLimit int64 = 64 * 1024 * 1024 // 64MB
	debug.SetMemoryLimit(memLimit)

	// ---------------------------
	// 配置加载
	// ---------------------------

	// 尝试多个配置文件路径
	configPaths := []string{
		"/etc/dkdns/dkdns.yaml",
		"etc/dkdns.yaml", // 相对于当前目录
	}

	var config *configs.Config
	var err error

	for _, path := range configPaths {
		config, err = configs.LoadConfig(path)
		if err == nil {
			break
		}
	}

	if err != nil {
		fmt.Printf("!!! 所有配置文件加载失败: %v\n", err)
		panic(err) // 触发 procd 重启
	}

	// ---------------------------
	// 日志系统初始化
	// ---------------------------
	if err := logger.InitLogger("logs/dkdns.log", 10); err != nil {
		fmt.Printf("初始化日志系统失败: %v\n", err)
		os.Exit(1)
	}

	// 设置全局panic处理
	defer func() {
		if r := recover(); r != nil {
			logger.Error("程序崩溃",
				fmt.Errorf("%v", r),
				zap.String("stack", string(debug.Stack())),
			)
			os.Exit(1)
		}
	}()

	logger.Println("√ 日志系统初始化完成")
	logger.Println(fmt.Sprintf("√ 已加载配置文件"))

	// ---------------------------
	// 服务启动
	// ---------------------------
	serviceExit := make(chan error, 1) // 服务退出通知

	// 启动 DNS 服务（带崩溃保护）
	go func() {
		defer func() {
			if r := recover(); r != nil {
				err := fmt.Errorf("DNS 服务崩溃: %v", r)
				logger.Error("DNS 服务崩溃", err)
				serviceExit <- err
			}
		}()
		logger.Println(">> 启动 DNS 服务...")
		dkdnserver.RunDNSServer(config)
	}()

	// 根据配置决定是否启动 DHCP 服务
	if config.DHCP.Enabled {
		logger.Info("正在启动 DHCP 服务...")
		if err := dkdnserver.RunDHCPServer(config); err != nil {
			logger.Error("启动 DHCP 服务失败", err)
		}
	} else {
		logger.Info("DHCP 服务已禁用")
	}

	// ---------------------------
	// 健康监控
	// ---------------------------
	go func() {
		ticker := time.NewTicker(30 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				logger.Info("健康检查", zap.String("message", "服务运行中"))
			case err := <-serviceExit:
				logger.Error("服务异常退出", err)
				panic(err) // 触发主程序崩溃，让 procd 重启
			}
		}
	}()

	// ---------------------------
	// 主协程阻塞
	// ---------------------------
	logger.Info("服务已就绪")
	select {} // 保持主协程存活
}
